package com.emellend.api.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.view.KeyEvent;
import android.view.View;

public class InternalSelectionView extends View {
	private int mNumRows = 5;
    private int mSelectedRow = 0;
    private final int mEstimatedPixelHeight = 10;
    
    private Paint mPainter = new Paint();
    private Paint mTextPaint = new Paint();
    private Rect mTempRect = new Rect();
    
    private Integer mDesiredHeight = null;
    private String mLabel = null;
	
	public InternalSelectionView(Context context,int numRows) {
		this(context, numRows,"");
	}


	public InternalSelectionView(Context context, AttributeSet attrs) {
		super(context, attrs);
		init();
	}

	public InternalSelectionView(Context context,int numRows,String label) {
		super(context);
		mNumRows=numRows;
		mLabel=label;
		init();
	}


	private void init() {
		setFocusable(true);
		mTextPaint.setAntiAlias(true);
		mTextPaint.setTextSize(10);
		mTextPaint.setColor(Color.WHITE);
	}


	public int getNumRows() {
		return mNumRows;
	}


	public int getSelectedRow() {
		return mSelectedRow;
	}


	public Integer getDesiredHeight() {
		return mDesiredHeight;
	}

	public void setDesiredHeight(int desiredHeight) {
        mDesiredHeight = desiredHeight;
    }
	
	public String getLabel() {
		return mLabel;
	}
	public int getRowHeight() {
		return (getHeight()-getPaddingTop()-getPaddingBottom())/mNumRows;
	}
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
		setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec));
	}

	private int measureWidth(int widthMeasureSpec) {
		int specMode = MeasureSpec.getMode(widthMeasureSpec);
		int specSize = MeasureSpec.getSize(widthMeasureSpec);
		int desiredWidth=300+getPaddingLeft()+getPaddingRight();
		
		if (specMode==MeasureSpec.EXACTLY) {
			return specSize;
		}else if (specMode==MeasureSpec.AT_MOST) {
			return specSize<desiredWidth?specSize:desiredWidth;
		}else {
			return desiredWidth;
		}
		
	}
	
	private int measureHeight(int heightMeasureSpec) {
		int specMode = MeasureSpec.getMode(heightMeasureSpec);
		int specSize = MeasureSpec.getSize(heightMeasureSpec);
		int desiredHeight=mDesiredHeight!=null?mDesiredHeight:
			mNumRows*mEstimatedPixelHeight+getPaddingBottom()+getPaddingTop();
		
		if (specMode==MeasureSpec.EXACTLY) {
			return specSize;
		}else if (specMode==MeasureSpec.AT_MOST) {
			return specMode<desiredHeight?specMode:desiredHeight;
		}else {
			return desiredHeight;
		}
	}
	
	@Override
	protected void onDraw(Canvas canvas) {
		final int rowHeight=getRowHeight();
		int rectTop=getPaddingTop();
		int rectLeft=getPaddingLeft();
		int rectRight=getWidth()-getPaddingRight();
		for(int i=0;i<mNumRows;i++){
			mPainter.setColor(Color.BLACK);
			mPainter.setAlpha(0x20);
			mTempRect.set(rectLeft, rectTop, rectRight, rectTop+rowHeight);
			canvas.drawRect(mTempRect, mPainter);
			if (i==mSelectedRow&&hasFocus()) {
				mPainter.setColor(Color.RED);
				mPainter.setAlpha(0xf0);
				mTextPaint.setAlpha(0xff);
			} else {
				mPainter.setColor(Color.BLACK);
				mPainter.setAlpha(0x40);
				mTextPaint.setAlpha(0xf0);
			}
			mTempRect.set(rectLeft+2, rectTop+2, rectRight-2, rectTop+rowHeight-2);
			canvas.drawRect(mTempRect, mPainter);
			canvas.drawText(Integer.toString(i), 
					rectLeft+2, 
					rectTop+2-mTextPaint.ascent(), mTextPaint);
			rectTop+=rowHeight;
		}
	}
	
	public void getRectForRow(Rect rect,int row){
		final int rowHeight=getRowHeight();
		final int top=getPaddingTop()+row*rowHeight;
		rect.set(getPaddingLeft(), top, getWidth()-getPaddingRight(), top+rowHeight);
	}
	void ensureRectVisible(){
		getRectForRow(mTempRect, mSelectedRow);
		requestRectangleOnScreen(mTempRect);
	}
	/**
	 * 按方向键的上下键，让当前被选择行改变。
	 * 注意，因为每个view都是由多个矩形块竖着叠起来的，所以，对每个view的操作只有上下两种，左右移动的话，是跨view
	 * 之间的移动，应该由下面两个方法实现。
	 */
	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		switch (event.getKeyCode()) {
		case KeyEvent.KEYCODE_DPAD_UP:
			if (mSelectedRow>0) {
				mSelectedRow--;
				invalidate();
				ensureRectVisible();
				return true;
			}
			break;

		case KeyEvent.KEYCODE_DPAD_DOWN:
			if (mSelectedRow<mNumRows-1) {
				mSelectedRow++;
				invalidate();
				ensureRectVisible();
				return true;
			}
			break;
		
		}
		return false;
	}
	/**
	 * 当焦点离开当前视图，而下一个视图获得焦点时，默认从这个方法里获得焦点的矩形信息。
	 * 默认情况下， 这个方法调用getDrawingRect来获得矩形信息，但是我们自己要实现一些内部选择等功能的时候，
	 * 就要自己提供矩形信息。
	 */
	@Override
	public void getFocusedRect(Rect r) {
		getRectForRow(r, mSelectedRow);
	}
	/**
	 * 当焦点改变时，若不实现这个方法，那么向左或者向右平移，下一列矩形获得焦点的列数会出现错误。
	 */
	@Override
	protected void onFocusChanged(boolean gainFocus, int direction,Rect previouslyFocusedRect) {
		super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
		if (gainFocus) {
			switch (direction) {
			case View.FOCUS_DOWN:
				mSelectedRow=0;
				break;
			case View.FOCUS_UP:
				mSelectedRow=mNumRows-1;
				break;
			case View.FOCUS_LEFT:
			case View.FOCUS_RIGHT:
				if (previouslyFocusedRect!=null) {
					int y=previouslyFocusedRect.top+(previouslyFocusedRect.height()/2);
					int yPerRow=getHeight()/mNumRows;
					mSelectedRow=y/yPerRow;
				}else {
					mSelectedRow=0;
				}
				break;

			default:
				return;
			}
			invalidate();
		}
	}
	@Override
	public String toString() {
		if (mLabel != null) {
            return mLabel;
        }
        return super.toString();
	}
}
